<?php
namespace app\common\model;
/**
 * 云峰风控公用model
 */
use think\Db;
use think\Model;
use yunfeng\TaskUtil;
use app\v2\model\UserInfo;
use think\cache\driver\Redis;

class YunFengModel extends Model
{
    protected $name = 'yunfeng_risk';
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    protected $autoWriteTimestamp = 'datetime';

    public function __construct()
    {
        parent::__construct();
        $config = config();

        $this->MONGO_PREFIX =$config['project_name'];//mogodb前缀 不同项目记得区分 TODO
        $this->SELECT =$config['redis_select'];//Redis 选择库
    }

    /**
     * 保存回调数据
     * @param  $param 回调参数
     * @return [type]           [description]
     */
    public function notifySaveData($param)
    {
        try {
            if($param['code'] == 'general_0' && $param['authStatus'] == "1"){
                $userGid = $param['userGid'];
                $data['userGid'] = $userGid;

                // 保存已经认证项目
                $data[$param['authType']]  = 1;
                
                // 保存四要素
                if(!empty($param['data']['idCardNo']) && $param['authType'] == 'debitcard'){
                    $data['idCardNo']         = $param['data']['idCardNo'];
                    $data['cardHolderName']   = $param['data']['cardHolderName'];
                    $data['phoneNo']          = $param['data']['phoneNo'];
                    $data['bankCardNo']       = $param['data']['bankCardNo'];
                }

                // 保存数据到mongodb 并存储其mongodb_id
                $saveMongo = self::saveToMongodb($userGid);
                if($saveMongo) {
                    $data['mongodb_id'] = $saveMongo['mongodb_id'];
                }

                //有则更新
                if($this->where('userGid', $userGid)->count() > 0){
                    $map['userGid'] = $userGid;
                }

                $res = $this->allowField(true)->save($data, $map);
                if($res){
                    return true;
                }
            }
            $this->error = "数据未保存";
            return false;

        } catch (\Exception $e) {
            $this->error = "数据保存失败";
            return false;
        }
    }


    /**
     * 获取链接
     * @return [type] [description]
     */
    public function getUrl($uid)
    {
        $UserInfoModel = new UserInfo;
        $UserInfo = $UserInfoModel->where('uid',$uid)->field('id_card,bind_mob,name,bank_card_number')->find();
        if(empty($UserInfo['bank_card_number']) || empty($UserInfo['bind_mob'])){
            $this->error = '请先完成银行卡认证';
            return false;  
        }

        $map['idCardNo']       = $UserInfo['id_card'];
        $map['cardHolderName'] = $UserInfo['name'];
        $map['bankCardNo']     = $UserInfo['bank_card_number'];
        $map['phoneNo']        = $UserInfo['bind_mob'];

        $redis = new Redis();
        $redis -> select($this->SELECT); //17号库
        $redisKey   = $this->MONGO_PREFIX.'_YunFengToken:'.$uid;
        $countToken = $this->MONGO_PREFIX.'_YunFengTokenCount';
        $token = $redis->get($redisKey);

        $bodyJson = ["data" => $map];
        if(!$token) {
            $getH5Token = TaskUtil::getH5Token($bodyJson);
            if(!empty($getH5Token['token'])){
                $token = $getH5Token['token'];
            }
            $redis->set($redisKey, $token, 3500);
            $redis ->inc($countToken);
        }

        $result = TaskUtil::getH5Url($token, $bodyJson);
        if(!$result) {
            $this->error = '链接获取失败，请重新获取';
            return false;  
        }
        return $result;  
    }


    /**
     * 查询结果
     * @return [type] [description]
     */
    public function getResult($uid)
    {
        $UserInfoModel = new UserInfo;
        $UserInfo = $UserInfoModel->where('uid',$uid)->field('id_card,bind_mob,name,bank_card_number')->find();
        if(empty($UserInfo['bank_card_number']) || empty($UserInfo['bind_mob']) || empty($UserInfo['name']) ||empty($UserInfo['id_card'])){
            $this->error = '未查询到四要素信息';
            return false; 
        }

        $map['idCardNo']       = $UserInfo['id_card'];
        $map['cardHolderName'] = $UserInfo['name'];
        $map['bankCardNo']     = $UserInfo['bank_card_number'];
        $map['phoneNo']        = $UserInfo['bind_mob'];

        $yunfengRisk = $this->where($map)->order('id desc')->field('mongodb_id, userGid')->find();
        if(empty($yunfengRisk)||empty($yunfengRisk['userGid'])){
            $this->error = '未进行其他认证';
            return false; 
        }

        $userGid = $yunfengRisk['userGid'];
        $res = Db::connect("db_mongo")->name($this->MONGO_PREFIX)->where(['_id'=>$yunfengRisk['mongodb_id']])->find();
        if(!$res) {
            $res = self::saveToMongodb($userGid);
            if(!$res) {
                $this->error = '数据获取失败';
                return false; 
            }
            $this->where($map)->update(["mongodb_id" => $res['mongodb_id']]);
        }
        $result = $res['data'];

        foreach ($result as $key => $value) {
            $result[$key] = json_decode($value, true);
        }

        if(!empty($result['h5_risk_management_1'])){
            $result['h5_risk_management_1']['authTypes'] = self::authTypes($result['h5_risk_management_1']['authTypes']);
            $result['h5_risk_management_1']['refuseReason'] = self::refuseReason($result['h5_risk_management_1']['refuseReason']);
        }

        return $result;
    }


    /**
     * 保存到mongodb
     * @param  [type] $userGid 四要素认证完成后，返回的用户Gid
     * @return [type]          [description]
     */
    public function saveToMongodb ($userGid) {
        $items = [
            'debitcard',          //银行卡实名验证
            'creditcard',         //信用卡实名验证
            'carrier',            //运营商数据
            'taobao',             //淘宝数据
            'jd',                 //京东数据
            'h5_risk_management_1'//风控模型
        ];

        foreach ($items as $value) {
            $res = TaskUtil::getResult($userGid, $value);
            if($res){
                $data[$value] = $res['data'];
            }
        }

        $insertId = Db::connect("db_mongo")->name($this->MONGO_PREFIX)->insertGetId(["data"=>$data]);
        if(!$insertId){
            return false;
        }

        $result = [
            'mongodb_id' => $insertId,
            'data'       => $data
        ];

        return $result;
    }


    /**
     * 是否云峰认证  这里判断的是四要素
     * @param  [type]  $uid [description]
     * @return string      0:未认证   1:已认证  2:认证中
     */
    public static function isYunFengAuth($uid)
    {
        $UserInfoModel = new UserInfo;
        $UserInfo = $UserInfoModel->where('uid',$uid)->field('id_card,bind_mob,name,bank_card_number')->find();
        if(empty($UserInfo['bank_card_number']) || empty($UserInfo['bind_mob']) || empty($UserInfo['name']) || empty($UserInfo['id_card'])){
            return '0'; 
        }
        $map['idCardNo']       = $UserInfo['id_card'];
        $map['cardHolderName'] = $UserInfo['name'];
        $map['bankCardNo']     = $UserInfo['bank_card_number'];
        $map['phoneNo']        = $UserInfo['bind_mob'];

        $yunfengRisk = Db::name('yunfeng_risk')->where($map)->find();
        if(!empty($yunfengRisk['debitcard']) || !empty($yunfengRisk['carrier'])){
            return '2';
        }
        if(!empty($yunfengRisk['h5_risk_management_1'])){
            return '1';
        }
        return '0';
    }


    /**
     * 创建风控模型任务
     * @param  [type] $uid [description]
     * @return [type]      [description]
     */
    public function fengkongTask($uid)
    {
        $userInfoModel = new UserInfo;
        $userInfo = $userInfoModel->where('uid',$uid)->find();

        $para['mongoRes']  = $userInfo['mongo_operator_report'];
        $para['idNumber']  = $userInfo['id_card'];
        $para['channel']   = config('operator_channel');
        $para['userId']    = $userInfo['operator_id'];
        $para['search_id'] = $userInfo['operator_search_id'];

        $result = curlPost('api.qhweidai.com/api/Detailreport', $para);
        if(!$result){
            $this->error = '运营商数据获取失败';
            return false;
        }
        $result = json_decode($result, true);
        if($result['code'] != 200){
            $this->error = '运营商数据查询失败';
            return false;
        }
        $jsonArr = $result['data']['JsonData']['json'];

// $monthArr = [];
// foreach ($jsonArr['call_log'] as $v1) {
//     $new[] = $v1['month_detail'];
// }
// foreach ($new as $v2) {
//     foreach ($v2 as $v3) {
//     $monthArr[] = $v3['month'];
//     }
// }
// $monthArr = array_unique($monthArr);
// arsort($monthArr);
// foreach ($monthArr as $value) {
//     $month[] = $value;
// }
// dump($month);


        foreach ($jsonArr['call_log'] as $key => $value) {
            $callArr[] = [
                "otherPhone"   => $jsonArr['call_log'][$key]['phone'],
                "callType"     => 0,  //0：主叫 1：被叫
                "startTime"    => $jsonArr['call_log'][$key]['last_contact_date'], 
                "callLocation" => $jsonArr['call_log'][$key]['phone_location'],
                "duration"     => $jsonArr['call_log'][$key]['talk_seconds'],
                "fee"          => 0.0 //本次通话话费
            ];
        }

        $arr = [
            "bankCardInfo"=>[
                "cardHolderName" => $userInfo['name'],
                "phoneNo"        => $userInfo['bind_mob'],
                "bankCardNo"     => $userInfo['bank_card_number'],
                "idCardNo"       => $userInfo['id_card']
            ],
            "carrierReport"=>[
                "userInfo"=>[
                    "phoneNo"  => $userInfo['bind_mob'],
                    "name"     => $userInfo['name'],
                    "identity" => $userInfo['id_card'],
                    "address"  => $jsonArr['basic_info']['phone_location'],
                    "openDate" => $jsonArr['basic_info']['reg_time']
                ],
                "callHistory"=>[
                    [
                        "month"=>date('Ym'),  //爬取月份
                        "details"=>$callArr
                    ]
                ]
            ]
        ];  

        $data = json_encode($arr);
        $bodyJson = [
            "callbackUrl" => config("domainPath")['api']."/v2/fengkongNotify",  //风控模型异步回调地址
            'data'        => base64_encode(gzencode($data)) //使用gzip压缩后再用base64进行编码
        ];

        $res = TaskUtil::submitTask($taskType="risk_management_1", $bodyJson);
        if(empty($res['taskNo'])){
            $this->error = '任务创建失败';
            return false;
        }

        $param['uid']         = $userInfo['uid'];
        $param['taskNo']      = $res['taskNo'];
        $param['taskStatus']  = $res['taskStatus'];
        $param['create_time'] = date('Y-m-d H:i:s');
        $add = Db::name("yunfeng_task")->insert($param);
        if(!$add){
            $this->error = '任务创建失败';
            return false;
        }
        return $res;
    }


    /**
     * 保存风控模型任务回调数据
     * @param  $param 回调参数
     * @return [type]           [description]
     */
    public function fengkongNotifySaveData($param){
        try{
            $where['taskNo']      = $param['taskNo'];
            $data['taskResult']  = json_encode($param['taskResult']);
            $data['taskStatus']  = $param['taskStatus'];
            $data['update_time'] = date('Y-m-d H:i:s');
            $res = Db::name("yunfeng_task")->where($where)->update($data);
            if(!$res){
                $this->error = '任务更新失败';
                return false;
            }
            return true;
        } catch (\Exception $e) {
            $this->error = '数据处理失败';
            return false;
        }
    }


    /**
     * 获取风控模型结果
     * @param  [type] $uid [description]
     * @return [type]      [description]
     */
    public function getFengKongResult($uid)
    {
        $res = Db::name("yunfeng_task")->where('uid',$uid)->order('id desc')->find();

        if($res['taskStatus'] == 'processing'){
            $this->error = '任务正在处理中，请稍等';
            return false;
        }

        // 没有风控结果 则新建任务
        if(!$res || empty($res['taskResult']) || empty($res['taskResult'])=="null"){  
            $task = $this->fengkongTask($uid);
            if($task){
                $this->error = '任务创建中，请等待两分钟再查询';
                return false;
            }else{
                $this->error = $this->getError();
                return false;
            }
        }

        $data = json_decode($res['taskResult'], true);
        $data['refuseReason'] = self::refuseReason($data['refuseReason']);

        // 和H5认证结果 出参保持一致
        $result['h5_risk_management_1'] = $data; 
        $result['h5_risk_management_1']['authTime'] = $res['update_time'];
        $result['h5_risk_management_1']['authTypes'] = "银行卡、运营商";
        
        return $result;
    }


    public static function authTypes($arr=[])
    {
        foreach ($arr as $key => $value) {
            switch ($value) {
                case 'debitcard':
                    $arr[$key] = '银行卡';
                    break;
                case 'creditcard':
                    $arr[$key] = '信用卡';
                    break;                
                case 'carrier':
                    $arr[$key] = '运营商';
                    break;                
                case 'taobao':
                    $arr[$key] = '淘宝数据';
                    break;                
                case 'jd':
                    $arr[$key] = '京东数据';
                    break;                
                case 'h5_risk_management_1':
                    $arr[$key] = '风控模型';
                    break;
                default:
                    $arr[$key] = '未知';
                    break;
            }
        }

        return $arr;
    }

    public static function refuseReason($code='')
    {
        switch ($code) {
            case '100':
                $result['reason'] = '不法分子';
                $result['description'] = '查明用户有犯罪记录等不法行为';
                break;
            case '101':
                $result['reason'] = '多头借贷';
                $result['description'] = '用户在多家平台产生过借贷行为';
                break;            
            case '102':
                $result['reason'] = '高风险区域';
                $result['description'] = '判断用户所在地为高风险地域';
                break;            
            case '103':
                $result['reason'] = '涉嫌不法';
                $result['description'] = '判断用户参与过赌，毒等不法活动';
                break;            
            case '104':
                $result['reason'] = '身份规则限制';
                $result['description'] = '因用户的年龄，性别，身份等因素导致用户无法申请此项贷款';
                break;            
            case '105':
                $result['reason'] = '身份认证失败';
                $result['description'] = '用户实名认证失败';
                break;            
            case '106':
                $result['reason'] = '失信名单';
                $result['description'] = '用户发生过逾期行为，为黑名单用户';
                break;            
            case '107':
                $result['reason'] = '疑似恶意欺诈';
                $result['description'] = '用户运营商账单，银行账单，淘宝交易等数据存在恶意造假嫌疑';
                break;            
            case '108':
                $result['reason'] = '信用评分不足';
                $result['description'] = '用户信用评分不足，可能数据不全或者提交资料未满足申请产品条件';
                break;
            default:
                $result['reason'] = '未知';
                $result['description'] = '未知';
                break;
        }

        return $result;
    }

}